﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Miris.HumanMilkAnalyser.DataModel;
using Miris.HumanMilkAnalyser.Service.Shared;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class DiagnosticMessageReferenceSetupViewModel : MyViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the DiagnosticMessageReferenceSetupViewModel class.
        /// </summary>
        public DiagnosticMessageReferenceSetupViewModel(IDataService dataService)
            : base(dataService) { }

        public override void ResetProperties()
        {
            try
            {
                base.ResetProperties();

                LoadDiagnosticMessageReferenceList();
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// The <see cref="SelectedMessageReference" /> property's name.
        /// </summary>
        public const string SelectedMessageReferencePropertyName = "SelectedMessageReference";

        private object _selectedMessageReference = null;

        /// <summary>
        /// Sets and gets the SelectedMessageReference property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public object SelectedMessageReference
        {
            get
            {
                return _selectedMessageReference;
            }

            set
            {
                if (_selectedMessageReference == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedMessageReferencePropertyName);
                _selectedMessageReference = value;
                RaisePropertyChanged(SelectedMessageReferencePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="DiagnosticMessageReferenceList" /> property's name.
        /// </summary>
        public const string DiagnosticMessageReferenceListPropertyName = "DiagnosticMessageReferenceList";

        private ObservableCollection<DiagnosticMessageReference> _diagnosticMessageReferenceList = new ObservableCollection<DiagnosticMessageReference>();

        /// <summary>
        /// Sets and gets the DiagnosticMessageReferenceList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<DiagnosticMessageReference> DiagnosticMessageReferenceList
        {
            get
            {
                return _diagnosticMessageReferenceList;
            }

            set
            {
                if (_diagnosticMessageReferenceList == value)
                {
                    return;
                }

                RaisePropertyChanging(DiagnosticMessageReferenceListPropertyName);
                _diagnosticMessageReferenceList = value;
                RaisePropertyChanged(DiagnosticMessageReferenceListPropertyName);
            }
        }

        private RelayCommand<int> _moveUpCommand;

        /// <summary>
        /// Gets the MoveUpCommand.
        /// </summary>
        public RelayCommand<int> MoveUpCommand
        {
            get
            {
                return _moveUpCommand
                    ?? (_moveUpCommand = new RelayCommand<int>(
                                          p =>
                                          {
                                              SelectedMessageReference = GeneralUtility.ChangeSelectedItemIndex<DiagnosticMessageReference>(DiagnosticMessageReferenceList,
                                                  p, p == 0 ? DiagnosticMessageReferenceList.Count - 1 : p - 1);
                                          },
                                          p => p == -1 ? false : true));
            }
        }

        private RelayCommand<int> _moveDownCommand;

        /// <summary>
        /// Gets the MoveDownCommand.
        /// </summary>
        public RelayCommand<int> MoveDownCommand
        {
            get
            {
                return _moveDownCommand
                    ?? (_moveDownCommand = new RelayCommand<int>(
                                          p =>
                                          {
                                              SelectedMessageReference = GeneralUtility.ChangeSelectedItemIndex<DiagnosticMessageReference>(DiagnosticMessageReferenceList,
                                                  p, p == DiagnosticMessageReferenceList.Count - 1 ? 0 : p + 1);
                                          },
                                          p => p == -1 ? false : true));
            }
        }

        private RelayCommand _saveCommand;

        /// <summary>
        /// Gets the SaveCommand.
        /// </summary>
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand
                    ?? (_saveCommand = new RelayCommand(
                                          () =>
                                          {
                                              try
                                              {
                                                  ServiceFactory.CreateDiagnosticMessageReferenceService().Synchronize(DiagnosticMessageReferenceList);

                                                  // Send ReturnHomeMessage to PageBase.
                                                  Messenger.Default.Send<int>(0, MainViewModel.ReturnHomeMessageToken);
                                              }
                                              catch
                                              {
                                                  RequestDisplayErrorMessage("无法保存，有非法数据格式，请检查输入的内容。");
                                              }
                                          }));
            }
        }

        /// <summary>
        /// Load the data from data source for initializing DiagnosticMessageReferenceList. 
        /// </summary>
        private void LoadDiagnosticMessageReferenceList()
        {
            var diagnosticMessageReferenceList = ServiceFactory.CreateDiagnosticMessageReferenceService().GetAll().OrderBy(m => m.OrderIndex);
            DiagnosticMessageReferenceList = new ObservableCollection<DiagnosticMessageReference>(diagnosticMessageReferenceList);
        }
    }
}